package cn.wolfcode.wms.service.impl;

import cn.wolfcode.wms.domain.*;
import cn.wolfcode.wms.mapper.ProductStockMapper;
import cn.wolfcode.wms.mapper.StockIncomeBillItemMapper;
import cn.wolfcode.wms.mapper.StockIncomeBillMapper;
import cn.wolfcode.wms.query.QueryObject;
import cn.wolfcode.wms.service.IStockIncomeBillService;
import cn.wolfcode.wms.util.PageResult;
import cn.wolfcode.wms.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Service
public class StockIncomeBillServiceImpl implements IStockIncomeBillService{

    @Autowired
    private StockIncomeBillMapper billMapper;
    @Autowired
    private StockIncomeBillItemMapper itemMapper;
    @Autowired
    private ProductStockMapper productStockMapper;

    public void saveOrUpdate(StockIncomeBill entity) {

        //判断是保存还是添加操作
        if (entity.getId() == null) {
           insert(entity);
        }else{
            update(entity);
        }
    }

    //保存的方法
    private void insert(StockIncomeBill entity) {
        //设置录入人(当前登陆的用户)
        entity.setInputUser(UserContext.getCurrentUser());
        //设置录入时间
        entity.setInputTime(new Date());
        //设置状态(未审核)
        entity.setStatus(StockIncomeBill.NORMAL);
        //定义两个变量.用来计算总数量和总金额
        BigDecimal totalNumber = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        //计算小计
        for (StockIncomeBillItem item : entity.getItems()) {
            //获取商品价格
            BigDecimal costPrice = item.getCostPrice();
            //获取商品的数量
            BigDecimal number = item.getNumber();
            BigDecimal amount = costPrice.multiply(number).setScale(2, RoundingMode.HALF_UP);
            //设置小计
            item.setAmount(amount);
            //计算总数量和总金额
            totalAmount = totalAmount.add(amount);
            totalNumber = totalNumber.add(number);
        }
        //设置总金额和总数量
        entity.setTotalAmount(totalAmount);
        entity.setTotalNumber(totalNumber);

        //先保存库存,在保存明细
        billMapper.insert(entity);

        //在保存操作中,最后才能保存明细
        for (StockIncomeBillItem item : entity.getItems()) {
            //设置id
            item.setBillId(entity.getId());
            itemMapper.insert(item);
        }
    }

    //更新的方法
    private void update(StockIncomeBill entity) {
        //判断是否已经审核了,只有没有审核才能更新
        StockIncomeBill old = billMapper.selectByPrimaryKey(entity.getId());
        if (old.getStatus() == StockIncomeBill.NORMAL) {
            //先删除之前对应的所有明细
            billMapper.deleteByRelation(old.getId());
            //定义两个变量,表示总金额和总数量
            BigDecimal totalNumber = BigDecimal.ZERO;
            BigDecimal totalAmount = BigDecimal.ZERO;
            //迭代出所有的明细
            for (StockIncomeBillItem item : entity.getItems()) {
                BigDecimal costPrice = item.getCostPrice();
                BigDecimal number = item.getNumber();
                BigDecimal amount = costPrice.multiply(number).setScale(2,RoundingMode.HALF_UP);
                item.setAmount(amount);
                totalAmount = totalAmount.add(amount);
                totalNumber = totalNumber.add(number);
                //保存明细
                item.setBillId(entity.getId());
                itemMapper.insert(item);
            }
            entity.setTotalNumber(totalNumber);
            entity.setTotalAmount(totalAmount);
            billMapper.updateByPrimaryKey(entity);
        }
    }

    public void delete(Long id) {
        //先删除明细
        billMapper.deleteByRelation(id);
        billMapper.deleteByPrimaryKey(id);
    }

    public StockIncomeBill get(Long id) {

        return billMapper.selectByPrimaryKey(id);
    }

    public PageResult queryResult(QueryObject qo) {
        Integer rows = billMapper.queryForCount(qo);
        //判断数据库中的记录数是否为null
        if (rows==0) {
            return PageResult.EMPRY_PAGE;
        }
        //===============
        //如果数据库中有数据
        List<StockIncomeBill> data = billMapper.queryForPage(qo);
        return new PageResult(data,rows,qo.getCurrentPage(),qo.getPageSize());
    }

    //审核的方法(好,我们来开始审核了)
    public void audit(Long id) {
        //判断当前的单据是否已经审核了,如果没有审核,那么就进去审核,如果审核了,那么此时就不需要在审核了
        StockIncomeBill incomeBill = billMapper.selectByPrimaryKey(id);
        if (incomeBill.getStatus() == StockIncomeBill.NORMAL) {
            //获取入库单存储的仓库
            Depot depot = incomeBill.getDepot();
            //迭代出入库单中所有的明细,依次添加到库存中
            for (StockIncomeBillItem item : incomeBill.getItems()) {
                //获取明细中的商品
                Product product = item.getProduct();
                //判断库存中是否已经存在有此商品,因为存在和不存在是不同的操作
                ProductStock stock = productStockMapper.selectByProductAndDepot(product.getId(), depot.getId());
                if (stock != null) {//表示库存中已经存在了同样的商品
                    //存在了,那么使用移动平均加权算法
                    BigDecimal amount = stock.getAmount().add(incomeBill.getTotalAmount());
                    BigDecimal number = stock.getStoreNumber().add(incomeBill.getTotalNumber());
                    BigDecimal price = amount.divide(number, RoundingMode.HALF_UP);
                    //设置商品库存的价格
                    stock.setPrice(price);
                    //设置总数量
                    stock.setStoreNumber(number);
                    //设置总金额
                    stock.setAmount(amount);
                    //更新库存
                    productStockMapper.updateByPrimaryKey(stock);
                }else{//表示库存中没有存在同样的商品

                    //创建一个库存对象
                    stock = new ProductStock();
                    //设置商品库存价格
                    stock.setPrice(item.getCostPrice());
                    //设置总数量
                    stock.setStoreNumber(item.getNumber());
                    //设置库存总金额
                    stock.setAmount(item.getAmount());
                    //设置商品
                    stock.setProduct(product);
                    //设置仓库
                    stock.setDepot(depot);
                    //保存到库存中
                    productStockMapper.insert(stock);
                }

            }
            //设置审核时间
            incomeBill.setAuditTime(new Date());
            //设置审核人
            incomeBill.setAuditor(UserContext.getCurrentUser());
            //改变审核状态
            incomeBill.setStatus(StockIncomeBill.AUDIT);
            //最后是审核单据
            billMapper.audit(incomeBill);
        }

    }

}
